home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume4 / unaxcess / part3 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  41.3 KB

  1. Subject: UNaXcess (3 of 3)
  2. Newsgroups: mod.sources
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 4, Issue 67
  6. Submitted by: decvax!cwruecmp!ncoast!allbery
  7.  
  8. #! /bin/sh
  9. # This is a shell archive, meaning:
  10. # 1. Remove everything above the #! /bin/sh line.
  11. # 2. Save the resulting text in a file.
  12. # 3. Execute the file with /bin/sh (not csh) to create the files:
  13. #    ua.c
  14. #    udl.c
  15. #    user.c
  16. # This archive created: Sat Apr 12 10:03:33 1986
  17. export PATH; PATH=/bin:$PATH
  18. echo shar: extracting "'ua.c'" '(8606 characters)'
  19. if test -f 'ua.c'
  20. then
  21.     echo shar: will not over-write existing file "'ua.c'"
  22. else
  23. cat << \SHAR_EOF > 'ua.c'
  24. /*
  25.  * %W% %E% %U% ncoast!bsa %Z%
  26.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  27.  */
  28.  
  29. #ifndef lint
  30. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  31. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  32. #endif  lint
  33.  
  34. #include "ua.h"
  35.  
  36. struct cmd
  37.     {
  38.     char c_ch;                /* command character */
  39.     char c_desc[33];            /* command description */
  40.     int (*c_exec)();            /* command executive */
  41.     }
  42.     ;                    /* used for command array */
  43.  
  44. /* forward references for command executives */
  45.  
  46. extern int
  47.     readmsg(),    readnew(),    confidx(),    enter(),
  48.     join(),        killmsg(),    helpme(),    scanmsg(),
  49.     logout(),    bulletin(),    linelen(),    shell(),
  50.     userctl(),    userlist(),    qscan(),    udl(),
  51.     unsub(),    setlconf();
  52.  
  53. struct cmd cmdt[] =
  54.     {
  55.     '?', "Print help messages",            helpme,
  56.     'a', "Alter or examine a user",        userctl,
  57.     'b', "Reprint login bulletins",        bulletin,
  58.     'c', "Shell command access",        shell,
  59.     'd', "Set default login conference",    setlconf,
  60.     'e', "Enter a message",            enter,
  61.     'f', "File area (Downloading)",        udl,
  62.     'g', "Exit UNaXcess",            logout,
  63.     'h', "Print help messages",            helpme,
  64.     'i', "Index of conferences",        confidx,
  65.     'j', "Join a new conference",        join,
  66.     'k', "Kill a message",            killmsg,
  67.     'l', "Set line length",            linelen,
  68.     'n', "Read all new messages",        readnew,
  69.     'q', "Quick scan of messages",        qscan,
  70.     'r', "Read messages in a conference",    readmsg,
  71.     's', "Scan messages",            scanmsg,
  72.     'u', "Unsubscribe from a conference",    unsub,
  73.     'w', "List of UNaXcess users",        userlist,
  74.     NULL,NULL,                    NULL
  75.     };
  76.  
  77. int nopause;
  78. jmp_buf cmdloop;
  79.  
  80. main(argc, argv)
  81.     char **argv;
  82.     {
  83.     char line[256], *lp;
  84.     short lcnt;
  85.     FILE *tp;
  86.  
  87.     getparms();
  88.     chdir(parms.ua_home);
  89.     logon();
  90.     if (parms.ua_hco == 1) {
  91.         printf("\nDo you wish me to stop every few lines to let you read messages (Y)? ");
  92.         gets(line);
  93.         log("Pause? %s", line);
  94.     }
  95.     if (parms.ua_hco == 0 || (parms.ua_hco == 1 && ToLower(line[0]) != 'n'))
  96.         nopause = 0;
  97.     else
  98.         nopause = 1;
  99.     alarm(parms.ua_tlimit * 60);        /* time limit */
  100.     signal(SIGINT, SIG_IGN);
  101.     signal(SIGQUIT, quit);
  102.     for (lcnt = 4; lcnt < SIGUSR1; lcnt++)    /* we don't muck with others */
  103.     signal(lcnt, logsig);
  104.     signal(SIGALRM, thatsall);
  105.     if (parms.ua_bnr[0] == '\0')
  106.     puts("\nWelcome to UNaXcess Version 0.04.03 (pre-release)\nCopyright (C) 1984, 1985 by Brandon Allbery");
  107.     else
  108.         cat(parms.ua_bnr);
  109.     if (argc > 2)
  110.     {
  111.     puts("To run UNaXcess from the shell, type `ua' or `ua username'.\nIf username has spaces or shell metacharacters in it, quote it.\n");
  112.     log("Invoked with %d arguments.  Goodbye.", argc);
  113.     exit(1);
  114.     }
  115.     else
  116.     argc--;
  117.     if (parms.ua_bbs[0] != '\0' && strcmp(getlogin(), parms.ua_bbs) == 0) {
  118.  
  119. nouser:
  120.         for (lcnt = 0; lcnt != 3; lcnt++) {
  121.          if (argc) {
  122.             strcpy(line, argv[1]);
  123.                 argc--;
  124.             putchar('\n');
  125.          }
  126.         else {
  127.                 if (parms.ua_login[0] == 0)
  128.                 printf("\nEnter your user name, GUEST, OFF, or NEW: ");
  129.             else
  130.                 fputs(parms.ua_login, stdout);
  131.             gets(line);
  132.         }
  133.     log("Login: %s", line);
  134.     if (line[0] == '\0')
  135.         {
  136.         lcnt--;
  137.         continue;
  138.         }
  139.     for (lp = line; *lp != '\0'; lp++)
  140.         *lp = ToLower(*lp);
  141.     if (strcmp(line, "off") == 0)
  142.         {
  143.         puts("Goodbye...\n\n");
  144.         log("Logout.");
  145.         exit(0);
  146.         }
  147.     if (!getuser(line, &user))
  148.         {
  149.         printf("No such user.\n");
  150.         log("No such user.");
  151.         }
  152.     else if (user.u_pass[0] != '\0')
  153.         {
  154.         strcpy(line, getpass("Enter your password: "));
  155.         log("Password: %s", line);
  156.         puts("\nChecking password...");
  157.         if (strcmp(crypt(line, line) + 2, user.u_pass) == 0)
  158.         break;
  159.         }
  160.     else
  161.         break;
  162.     }
  163.     if (parms.ua_nla > 0 && lcnt == parms.ua_nla)
  164.     {
  165.     puts("\nSorry, you blew it.");
  166.     log("Program aborted.");
  167.     exit(1);
  168.     }
  169.     }
  170.     else if (!getuser(getlogin(), &user))
  171.         goto nouser;
  172.     log("%s, access = %d, sys = %s, line = %d", user.u_name, user.u_access, user.u_login, user.u_llen);
  173.     if (user.u_access == A_NONE)
  174.     {
  175.     puts("Your access privileges have been revoked.  Goodbye...\n\n");
  176.     log("Security violation:  access revoked.");
  177.     exit(1);
  178.     }
  179.     if ((tp = fopen(RIndex(ttyname(fileno(stdin)), '/') + 1, "w")) == NULL)
  180.     {
  181.     log("Error %d opening %s", errno, RIndex(ttyname(fileno(stdin)), '/') + 1);
  182.     log("Non-interactive session not logged to terminal.");
  183.     }
  184.     else {
  185.     fprintf(tp, "%s on as \"%s\" on %s\n", getlogin(), user.u_name, longdate());
  186.     fclose(tp);
  187.     }
  188.     putchar('\n');
  189.     if (user.u_access != A_MKUSER)
  190.     bulletin(NULL);
  191.     umask(0);                    /* so xedit() works */
  192.     if (user.u_lconf[0] != '\0')
  193.         if (isconf(user.u_lconf))
  194.             strcpy(conference, user.u_lconf);
  195.         else {
  196.             putchar('\n');
  197.             for (lp = parms.ua_sysop; *lp != '\0'; lp++)
  198.                 putchar(ToUpper(*lp));
  199.             printf(" deleted \"%s\", your login conference.  I'm setting you\nback to the \"general\" conference.\n", user.u_lconf);
  200.             user.u_lconf[0] = '\0';
  201.             strcpy(conference, "general");
  202.         }
  203.     else
  204.         strcpy(conference, "general");
  205.     hicnts = readhigh(&user);
  206.     cleanhigh();    /* kill any lingering corpses */
  207.     if (!setjmp(cmdloop))
  208.     signal(SIGINT, intrp);
  209.     while (cmd())
  210.     ;
  211.     printf("Goodbye, ");
  212.     for (lp = user.u_name; *lp != '\0'; lp++)
  213.     putchar(ToUpper(*lp));
  214.     printf(".  Call again soon!\n\n\n");
  215.     log("Logout.");
  216.     cleanup();
  217.     }
  218.  
  219. cleanup()
  220.     {
  221.     char tmps[256];
  222.     FILE *fp;
  223.  
  224.     sprintf(tmps, "%s/himotd", MOTD);
  225.     if ((fp = fopen(tmps, "r")) == NULL)
  226.     {
  227.     log("Error %d opening %s", errno, tmps);
  228.     panic("himotd");
  229.     }
  230.     fgets(tmps, 32, fp);
  231.     fclose(fp);
  232.     user.u_nbull = atoi(tmps);
  233.     putuser(user.u_name, &user);
  234.     unlink(RIndex(ttyname(2), '/') + 1);
  235.     exit(0);
  236.     }
  237.  
  238. cmd()
  239.     {
  240.     char line[256], *p;
  241.     struct cmd *cmdp;
  242.  
  243.     if (user.u_access == A_MKUSER) {
  244.     newuser();
  245.     if (user.u_access == A_NONE) {
  246.         puts("\nYou'll have to be validated before you can use UNaXcess.");
  247.         return 0;
  248.     }
  249.     }
  250.     printf("\n(%s) Command (? = Help): ", conference);
  251.     gets(line);
  252.     log("Command: %s", line);
  253.     if (line[0] == '\0')
  254.     return 1;
  255.     for (p = line; *p != '\0'; p++)
  256.     *p = ToLower(*p);
  257.     for (cmdp = cmdt; cmdp->c_ch != NULL; cmdp++)
  258.     if (ToLower(cmdp->c_ch) == line[0])
  259.         return (*cmdp->c_exec)(line);
  260.     puts("Type '?' for help.");
  261.     log("No such command.");
  262.     return 1;
  263.     }
  264.  
  265. logout()
  266.     {
  267.     char line[256];
  268.  
  269.     printf("Are you sure you want to log out (N)? ");
  270.     gets(line);
  271.     log("Logout? %s", line);
  272.     return (ToLower(line[0]) != 'y');
  273.     }
  274.  
  275. helpme()
  276.     {
  277.     short lcnt;
  278.     struct cmd *cmdp;
  279.  
  280.     putchar('\n');
  281.     lcnt = 2 * ((user.u_llen < 80) + 1);
  282.     for (cmdp = cmdt; cmdp->c_ch != NULL; cmdp++)
  283.     {
  284.     printf("%c - %-32.32s", ToUpper(cmdp->c_ch), cmdp->c_desc);
  285.     lcnt++;
  286.     if (user.u_llen < 80 || !(lcnt % 2))
  287.         putchar('\n');
  288.     if ((lcnt / 2) % (user.u_llen >= 80? 32: 16) == 0)
  289.         if (!cont())
  290.         break;
  291.     }
  292.     if (user.u_llen >= 80 && lcnt % 2 != 0)
  293.         putchar('\n');
  294.     puts("\nIf you need further help, look for (or ask for) a HELP conference.");
  295.     return 1;
  296.     }
  297.  
  298. linelen(s)
  299.     char *s;
  300.     {
  301.     int llen;
  302.     char line[256], *p;
  303.  
  304.     p = s;
  305.     while (*p != '\0')
  306.     if (*p++ == ' ')
  307.         if ((llen = atoi(p)) > 40 && llen < 132)
  308.         {
  309.         printf("New line length = %d.\n", llen);
  310.         user.u_llen = llen;
  311.         putuser(user.u_name, &user);
  312.         return 1;
  313.         }
  314.         else
  315.         break;
  316.     llen = 0;
  317.     while (llen < 40 || llen > 132)
  318.     {
  319.     printf("\nEnter new line length (40-132): ");
  320.     gets(line);
  321.     llen = atoi(line);
  322.     }
  323.     return 1;
  324.     }
  325.  
  326. cont()
  327.     {
  328.     char ch;
  329.  
  330.     if (!isatty(0) || nopause)
  331.     return 1;
  332.     printf("More (Y)? ");
  333.     silent();
  334.     ch = getchar();
  335.     talk();
  336.     log("Cont? %c", ch);
  337.     printf("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b");
  338.     return (RIndex(" Yy\r\n", ch) != NULL);
  339.     }
  340.  
  341. cat(file)
  342.     char *file;
  343.     {
  344.     FILE *f;
  345.     char ch;
  346.     short lcnt, ccnt;
  347.  
  348.     if ((f = fopen(file, "r")) == NULL)
  349.     {
  350.     log("Error %d opening %s", errno, file);
  351.     puts("Cannot open file.");
  352.     return;
  353.     }
  354.     lcnt = ccnt = 0;
  355.     while ((ch = getc(f)) != EOF)
  356.     {
  357.     if (ch == '\n')
  358.         {
  359.         putchar(ch);
  360.         ccnt = 0;
  361.         if (++lcnt % 16 == 0)
  362.         if (!cont())
  363.             break;
  364.         }
  365.     else if (ch == '\t')
  366.         putchar('\t');
  367.     else
  368.         {
  369.         if (iscntrl(ch))
  370.         putchar('.');
  371.         else
  372.         putchar(ch);
  373.         if (++ccnt == (user.u_llen<40? 80: user.u_llen) - 1)
  374.         {
  375.         ccnt = 0;
  376.         putchar('\n');
  377.         if (++lcnt % 16 == 0)
  378.             if (!cont())
  379.             break;
  380.         }
  381.         }
  382.     }
  383.     fclose(f);
  384.     }
  385. SHAR_EOF
  386. if test 8606 -ne "`wc -c < 'ua.c'`"
  387. then
  388.     echo shar: error transmitting "'ua.c'" '(should have been 8606 characters)'
  389. fi
  390. fi
  391. echo shar: extracting "'udl.c'" '(15435 characters)'
  392. if test -f 'udl.c'
  393. then
  394.     echo shar: will not over-write existing file "'udl.c'"
  395. else
  396. cat << \SHAR_EOF > 'udl.c'
  397. /*
  398.  * %W% %E% %U% ncoast!bsa %Z%
  399.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  400.  */
  401.  
  402. #ifndef lint
  403. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  404. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  405. #endif  lint
  406.  
  407. #include "ua.h"
  408. #ifdef BSD
  409. #include <sys/time.h>
  410. #else  SYS3
  411. #include <time.h>
  412. #endif BSD
  413.  
  414. #define A_UPLOAD    parms.ua_auc
  415. #define A_DOWNLOAD    parms.ua_adc
  416.  
  417. #define X_UPLOAD    parms.ua_xuc
  418. #define X_DOWNLOAD    parms.ua_xdc
  419.  
  420. #define K_UPLOAD    parms.ua_kuc
  421. #define K_DOWNLOAD    parms.ua_kdc
  422.  
  423. #define LIBRARY        "library"
  424. #define DIRECTORY    "directory"
  425. #define STORAGE        "uploads"
  426. #define UPLOG        "upload-log"
  427.  
  428. #define off        0
  429. #define on        1
  430.  
  431. #define pager        __col = 0, __line = 0, __Page =
  432.  
  433. #define DIRFORMAT    "%[^ ] %*1[Ff]%*1[Ii]%*1[Ll]%*1[Ee] %[^;]; %[^ ] %*1[Bb]%*1[Yy] %[^:]: %[^\n]"
  434.  
  435. jmp_buf brchloop, fileloop;
  436. static char thisbrch[80] = "";
  437.  
  438. int __Page = on;
  439. int __line = 0;
  440. int __col = 0;
  441. int __paws = off;
  442.  
  443. char *whatis(), *pgetin(), *cpmform(), *upstr(), *today();
  444.  
  445. extern struct tm *localtime();
  446.  
  447. udl(branch)
  448. char *branch; {
  449.     int again();
  450.     int (*oldint)();
  451.     char *cp;
  452.  
  453.     if (user.u_access < A_FILES) {
  454.         puts("\nYou will not be able to upload or download files.\nYou may, however, download File Lists.");
  455.         log("File Section entered; access restricted");
  456.     }
  457.     thisbrch[0] == '\0';
  458.     for (cp = branch; *cp != '\0'; cp++)
  459.         if (*cp == ' ') {
  460.             strcpy(thisbrch, ++cp);
  461.             break;
  462.         }
  463.     oldint = signal(SIGINT, again);
  464.     setjmp(brchloop);
  465.     while (libmenu())
  466.         ;
  467.     msg("\n");
  468.     signal(SIGINT, oldint);
  469. }
  470.  
  471. again() {
  472.     signal(SIGINT, again);
  473.     pager on;
  474.     msg("\nInterrupt\n");
  475.     fflush(stdout);
  476.     log("Interrupt");
  477.     if (__paws == on) {
  478.         talk();
  479.         __paws = off;
  480.     }
  481.     longjmp(brchloop, 1);
  482. }
  483.  
  484. libmenu() {
  485.     struct direct *branch;
  486.     DIR *library;
  487.     char cmd[512], bname[512];
  488.     int (*oldsig)();
  489.     int brch_cmd();
  490.     char *desc;
  491.     
  492.     if ((library = opendir(LIBRARY)) == NULL) {
  493.         msg("The Library is closed\n");
  494.         return 0;
  495.     }
  496.     if (thisbrch[0] != '\0') {
  497.         strcpy(cmd, thisbrch);
  498.         thisbrch[0] == '\0';
  499.         goto gotbrch;
  500.     }
  501.     msg("\nThe UNaXcess File Section.  Please select one of the following\nbranches, or EXIT to leave the Library.\n\n");
  502.     while ((branch = readdir(library)) != NULL) {
  503.         if ((desc = whatis(branch->d_name, NULL)) == NULL)
  504.             continue;
  505.         msg("    %-8.8s   %s\n", upstr(branch->d_name), desc);
  506.     }
  507.     closedir(library);
  508.     msg("\nBranch: ");
  509.     if (pgetin(cmd, NULL) == NULL)
  510.         return 0;
  511.     log("Branch: %s", cmd);
  512.     if (s_cmp(cmd, "EXIT") == 0)
  513.         return 0;
  514.  
  515. gotbrch:
  516.     if (whatis(cmd, NULL) != NULL) {
  517.         library = opendir(LIBRARY);
  518.         while ((branch = readdir(library)) != NULL)
  519.             if (s_cmp(branch->d_name, cmd) == 0) {
  520.                 closedir(library);
  521.                 strcpy(bname, branch->d_name);
  522.                 oldsig = signal(SIGINT, brch_cmd);
  523.                 setjmp(fileloop);
  524.                 while (visit(bname))
  525.                     ;
  526.                 signal(SIGINT, oldsig);
  527.                 return 1;
  528.             }
  529.     }
  530.     closedir(library);
  531.     msg("There is no such branch.  If you wish to open a new branch,\nleave a message to %s.\n", parms.ua_sysop);
  532.     return 1;
  533. }
  534.  
  535. visit(branch)
  536. char *branch; {
  537.     char cmd[512];
  538.     DIR *directory;
  539.     
  540.     sprintf(cmd, "%s/%s", LIBRARY, branch);
  541.     if ((directory = opendir(cmd)) == NULL) {
  542.         msg("The %s branch is closed.\n", upstr(branch));
  543.         return 0;
  544.     }
  545.     closedir(directory);
  546.     msg("\n%s Branch\nUpload, Download, List of Files, Get File List, Exit: ", upstr(branch));
  547.     if (pgetin(cmd, NULL) == NULL)
  548.         return 0;
  549.     log("Branch cmd: %s", cmd);
  550.     switch (cmd[0]) {
  551.         case 'e':
  552.         case 'E':
  553.             return 0;
  554.         case 'U':
  555.         case 'u':
  556.             upload(branch);
  557.             break;
  558.         case 'D':
  559.         case 'd':
  560.             download(branch);
  561.             break;
  562.         case 'L':
  563.         case 'l':
  564.             filelist(branch);
  565.             break;
  566.         case 'G':
  567.         case 'g':
  568.             getlist(branch);
  569.             break;
  570.         default:
  571.             msg("Unrecognized command.\n");
  572.     }
  573.     return 1;
  574. }
  575.  
  576. brch_cmd() {
  577.     pager on;
  578.     msg("\nInterrupt\n");
  579.     log("Interrupt");
  580.     fflush(stdout);
  581.     if (__paws == on) {
  582.         talk();
  583.         __paws = off;
  584.     }
  585.     signal(SIGINT, brch_cmd);
  586.     longjmp(fileloop, 1);
  587. }
  588.  
  589. filelist(branch)
  590. char *branch; {
  591.     char path[512];
  592.     DIR *directory;
  593.     struct direct *file;
  594.     char *desc;
  595.  
  596.     sprintf(path, "%s/%s", LIBRARY, branch);
  597.     directory = opendir(path);
  598.     msg("\nFile Directory for the %s Branch:\n\n", upstr(branch));
  599.     while ((file = readdir(directory)) != NULL) {
  600.         if ((desc = whatis(branch, file->d_name)) == NULL)
  601.             continue;
  602.         msg("    %-12.12s   %s\n", cpmform(file->d_name), desc);
  603.     }
  604.     msg("\n");
  605.     closedir(directory);
  606. }
  607.  
  608. getlist(branch)
  609. char *branch; {
  610.     char path[512], listfile[30], cmd[512];
  611.     DIR *directory;
  612.     struct direct *file;
  613.     int (*oldsig)();
  614.     char *desc;
  615.     FILE *list;
  616.  
  617.     sprintf(listfile, "/tmp/cli%05d", getpid());
  618.     if ((list = fopen(listfile, "w")) == NULL) {
  619.         msg("Can't open temporary list file???\n");
  620.         exit(5);
  621.     }
  622.     msg("\nDownload file listing from the %s branch\n\nSupported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch));
  623.     if (pgetin(cmd, NULL) == NULL)
  624.         return;
  625.     log("List dnld mode: %s", cmd);
  626.     switch (cmd[0]) {
  627.         case 'A':
  628.         case 'a':
  629.             if (!validudl(A_DOWNLOAD)) {
  630.                 msg("\nAscii Download is not supported.\n");
  631.                 log("No Ascii");
  632.                 return;
  633.             }
  634.             sprintf(cmd, A_DOWNLOAD, listfile);
  635.             break;
  636.         case 'K':
  637.         case 'k':
  638.             if (!validudl(K_DOWNLOAD)) {
  639.                 msg("\nKermit Download is not supported.\n");
  640.                 log("No Kermit");
  641.                 return;
  642.             }
  643.             sprintf(cmd, K_DOWNLOAD, listfile);
  644.             break;
  645.         case 'X':
  646.         case 'x':
  647.             if (!validudl(X_DOWNLOAD)) {
  648.                 msg("\nXModem Download is not supported.\n");
  649.                 log("No Xmodem");
  650.                 return;
  651.             }
  652.             sprintf(cmd, X_DOWNLOAD, listfile);
  653.             break;
  654.         case '\0':
  655.             cmd[0] = 'X';
  656.             if (!validudl(X_DOWNLOAD)) {
  657.                 msg("\nXModem Download is not supported.\n");
  658.                 log("No Xmodem");
  659.                 return;
  660.             }
  661.             sprintf(cmd, X_DOWNLOAD, listfile);
  662.             break;
  663.         default:
  664.             msg("Invalid protocol designation.\n");
  665.             return;
  666.     }
  667.     sprintf(path, "%s/%s", LIBRARY, branch);
  668.     directory = opendir(path);
  669.     fprintf(list, "File Directory for the %s Branch:\r\n\r\n", upstr(branch));
  670.     while ((file = readdir(directory)) != NULL) {
  671.         if ((desc = whatis(branch, file->d_name)) == NULL)
  672.             continue;
  673.         fprintf(list, "    %-12.12s   %s\r\n", cpmform(file->d_name), desc);
  674.     }
  675.     fclose(list);
  676.     closedir(directory);
  677.     msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n");
  678.     fflush(stdout);
  679.     sleep(30);
  680.     oldsig = signal(SIGINT, SIG_IGN);
  681.     system(cmd);
  682. #ifdef SYS3
  683.     system("stty echoe");
  684. #endif SYS3
  685.     signal(SIGINT, oldsig);
  686.     unlink(listfile);
  687. }
  688.  
  689. download(branch)
  690. char *branch; {
  691.     char path[512], filename[512], cmd[512];
  692.     DIR *directory;
  693.     struct direct *file;
  694.     int (*oldsig)();
  695.     
  696.     if (user.u_access < A_FILES) {
  697.         log("Attempted download, access denied.");
  698.         puts("You may not download files.");
  699.         return;
  700.     }
  701.     msg("\nDownload from the %s branch\n\nEnter file to download: ");
  702.     if (pgetin(filename, NULL) == NULL)
  703.         return;
  704.     log("Dnld file: %s", filename);
  705.     if (filename[0] == '.' || Index(filename, '/') != NULL) {
  706.         msg("No such file: \"%s\"\n", upstr(filename));
  707.         return;
  708.     }
  709.     if (whatis(branch, filename) != NULL) {
  710.         sprintf(path, "%s/%s", LIBRARY, branch);
  711.         directory = opendir(path);
  712.         while ((file = readdir(directory)) != NULL) {
  713.             if (s_cmp(file->d_name, filename) == 0) {
  714.                 closedir(directory);
  715.                 sprintf(path, "%s/%s/%s", LIBRARY, branch, file->d_name);
  716.                 msg("Supported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch));
  717.                 if (pgetin(cmd, NULL) == NULL)
  718.                     return;
  719.                 switch (cmd[0]) {
  720.                     case 'A':
  721.                     case 'a':
  722.                         if (!validudl(A_DOWNLOAD)) {
  723.                             msg("\nAscii Download is not supported.\n");
  724.                             log("No Ascii");
  725.                             return;
  726.                         }
  727.                         sprintf(cmd, A_DOWNLOAD, path);
  728.                         break;
  729.                     case 'K':
  730.                     case 'k':
  731.                         if (!validudl(K_DOWNLOAD)) {
  732.                             msg("\nKermit Download is not supported.\n");
  733.                             log("No Kermit");
  734.                             return;
  735.                         }
  736.                         sprintf(cmd, K_DOWNLOAD, path);
  737.                         break;
  738.                     case 'X':
  739.                     case 'x':
  740.                         if (!validudl(X_DOWNLOAD)) {
  741.                             msg("\nXModem Download is not supported.\n");
  742.                             log("No Xmodem");
  743.                             return;
  744.                         }
  745.                         sprintf(cmd, X_DOWNLOAD, path);
  746.                         break;
  747.                     case '\0':
  748.                         cmd[0] = 'X';
  749.                         if (!validudl(X_DOWNLOAD)) {
  750.                             msg("\nXModem Download is not supported.\n");
  751.                             log("No Xmodem");
  752.                             return;
  753.                         }
  754.                         sprintf(cmd, X_DOWNLOAD, path);
  755.                         break;
  756.                     default:
  757.                         msg("Invalid protocol designation.\n");
  758.                         return;
  759.                 }
  760.                 msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n");
  761.                 fflush(stdout);
  762.                 sleep(30);
  763.                 oldsig = signal(SIGINT, SIG_IGN);
  764.                 system(cmd);
  765. #ifdef SYS3
  766.                 system("stty echoe");
  767. #endif SYS3
  768.                 signal(SIGINT, oldsig);
  769.                 return;
  770.             }
  771.         }
  772.         closedir(directory);
  773.     }
  774.     msg("No such file: \"%s\"\n", upstr(filename));
  775.     log("No such file");
  776. }
  777.  
  778. upload(branch)
  779. char *branch; {
  780.     char path[512], filename[512], cmd[512], desc[512];
  781.     DIR *directory;
  782.     struct direct *file;
  783.     int (*oldsig)();
  784.     FILE *logf;
  785.     
  786.     if (user.u_access < A_FILES) {
  787.         log("Attempted upload, access denied.");
  788.         puts("You may not upload files.");
  789.         return;
  790.     }
  791.     msg("\nUpload to the %s branch\n\nEnter the name to give the new file: ");
  792.     if (pgetin(filename, NULL) == NULL)
  793.         return;
  794.     log("Upld file: %s", filename);
  795.     if (filename[0] == '.' || Index(filename, '/') != NULL || Index(filename, ';') != NULL) {
  796.         msg("Invalid filename: \"%s\"\n", upstr(filename));
  797.         log("Invalid filename");
  798.         return;
  799.     }
  800.     sprintf(path, "%s/%s", STORAGE, branch);
  801.     if ((directory = opendir(path)) == NULL) {
  802.         msg("The %s has denied upload ability for this branch.\n", parms.ua_sysop);
  803.         return;
  804.     }
  805.     while ((file = readdir(directory)) != NULL) {
  806.         if (s_cmp(file->d_name, filename) == 0) {
  807.             closedir(directory);
  808.             msg("That file name is used.  Please try again with a different filename.\n");
  809.             log("File exists");
  810.             return;
  811.         }
  812.     }
  813.     closedir(directory);
  814.     msg("Enter a description for the file: ");
  815.     if (pgetin(desc, NULL) == NULL)
  816.         return;
  817.     log("Description: %s", desc);
  818.     if ((logf = fopen(UPLOG, "a")) == NULL) {
  819.         log("Error %d opening %s", errno, UPLOG);
  820.         msg("Can't log the new file.\n");
  821.         return;
  822.     }
  823.     fprintf(logf, "%s file %s; %s by %s: %s\n", branch, filename, today(), upstr(user.u_name), desc);
  824.     fclose(logf);
  825.     sprintf(path, "%s/%s/%s", STORAGE, branch, filename);
  826.     msg("Supported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch));
  827.     if (pgetin(cmd, NULL) == NULL)
  828.         return;
  829.     log("Upld protocol: %s", cmd);
  830.     switch (cmd[0]) {
  831.         case 'A':
  832.         case 'a':
  833.             if (!validudl(A_UPLOAD)) {
  834.                 msg("\nAscii Upload is not supported.\n");
  835.                 log("No Ascii");
  836.                 return;
  837.             }
  838.             sprintf(cmd, A_UPLOAD, path);
  839.             break;
  840.         case 'K':
  841.         case 'k':
  842.             if (!validudl(K_UPLOAD)) {
  843.                 msg("\nKermit Upload is not supported.\n");
  844.                 log("No Kermit");
  845.                 return;
  846.             }
  847.             sprintf(cmd, K_UPLOAD, path);
  848.             break;
  849.         case 'X':
  850.         case 'x':
  851.             if (!validudl(X_UPLOAD)) {
  852.                 msg("\nXModem Upload is not supported.\n");
  853.                 log("No Xmodem");
  854.                 return;
  855.             }
  856.             sprintf(cmd, X_UPLOAD, path);
  857.             break;
  858.         case '\0':
  859.             cmd[0] = 'X';
  860.             if (!validudl(X_UPLOAD)) {
  861.                 msg("\nXModem Upload is not supported.\n");
  862.                 log("No Xmodem");
  863.                 return;
  864.             }
  865.             sprintf(cmd, X_UPLOAD, path);
  866.             break;
  867.         default:
  868.             msg("Invalid protocol designation.\n");
  869.             return;
  870.     }
  871.     msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n");
  872.     fflush(stdout);
  873.     sleep(30);
  874.     oldsig = signal(SIGINT, SIG_IGN);
  875.     system(cmd);
  876. #ifdef SYS3
  877.     system("stty echoe");
  878. #endif SYS3
  879.     signal(SIGINT, oldsig);
  880. }
  881.  
  882. /*
  883.  * The following code is snarfed from UNaXcess V1.0, primarily as a test.
  884.  * Some audacious soul may want to backport this to the rest of UA...
  885.  */
  886.  
  887. msg(argp)
  888. int *argp; {
  889.     int **ap;
  890.     char buf[BUFSIZ];
  891.     FILE prwbuf;
  892.     register int *fp;
  893.     register char *cp;
  894. #ifdef USE_PRINT
  895.     extern FILE *_pfile;
  896. #endif USE_PRINT
  897.     
  898.     ap = &argp;
  899.     ap++;
  900.     prwbuf._flag = _IOWRT|_IOSTRG;
  901.     prwbuf._cnt = 32767;
  902.     prwbuf._ptr = buf;
  903.     prwbuf._base = buf;
  904.     fp = *(ap - 1);
  905. #ifdef USE_PRINT
  906.     _pfile = &prwbuf;
  907.     _print(fp, &ap);
  908. #else  USE_PRINT
  909.     argp++;
  910.     _doprnt(fp, &argp, &prwbuf);
  911. #endif USE_PRINT
  912.     putc('\0', &prwbuf);
  913.     for (cp = buf; *cp != '\0'; cp++)
  914.         say(*cp);
  915. }
  916.  
  917. say(ch)
  918. char ch; {
  919.     ch &= 0x7f;
  920.     switch (ch) {
  921.         case '\t':
  922.             do {
  923.                 say(' ');
  924.             } while (__col % 8);
  925.             break;
  926.         case '\n':
  927.             putchar('\n');
  928.             __col = 0;
  929.             if (__Page == on && ++__line == 23) {
  930.                 paws();
  931.                 __line = 0;
  932.             }
  933.             break;
  934.         case '\177':
  935.             msg("^?");
  936.             break;
  937.         default:
  938.             if (ch < ' ') {
  939.                 say('^');
  940.                 say(ch + '@');
  941.                 return;
  942.             }
  943.             if (__col == user.u_llen - 1)
  944.                 say('\n');
  945.             putchar(ch);
  946.             __col++;
  947.     }
  948. }
  949.  
  950. paws() {
  951.     fputs("Type any key to continue. . .", stdout);
  952.     __paws = on;
  953.     silent();
  954.     getchar();
  955.     talk();
  956.     __paws = off;
  957.     fputs("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b", stdout);
  958. }
  959.  
  960. s_cmp(s1, s2)
  961. char *s1, *s2; {
  962.     for (; *s1 != '\0' && ToLower(*s1) == ToLower(*s2); s1++, s2++)
  963.         ;
  964.     return (!(*s1 == '\0' && *s2 == '\0'));
  965. }
  966.  
  967. char *whatis(branch, file)
  968. char *branch, *file; {
  969.     static FILE *directory = NULL;
  970.     static char dent[512];
  971.     char tbr[512], tfi[512], date[512], who[512], desc[512];
  972.     
  973.     if (directory != NULL || (directory = fopen(DIRECTORY, "r")) != NULL) {
  974.         fseek(directory, 0L, 0);
  975.         while (fgets(dent, sizeof dent, directory) != NULL) {
  976.             if (dent[0] == '%' || dent[0] == '\n')
  977.                 continue;
  978.             tbr[0] = '\0';
  979.             tfi[0] = '\0';
  980.             date[0] = '\0';
  981.             who[0] = '\0';
  982.             desc[0] = '\0';
  983.             sscanf(dent, DIRFORMAT, tbr, tfi, date, who, desc);
  984.             if (s_cmp(tbr, branch) == 0) {
  985.                 if (s_cmp(tfi, (file == NULL? "branch": file)) != 0)
  986.                     continue;
  987.                 sprintf(dent, "%s [Created %s by %s]", desc, date, who);
  988.                 return dent;
  989.             }
  990.         }
  991.     }
  992.     log("No download directory");
  993.     return NULL;
  994. }
  995.  
  996. /* this is a stub-ified version of v1.0 COMND input module */
  997.  
  998. char *pgetin(str, tab)
  999. char *str;
  1000. char tab[]; {
  1001.     char *ch;
  1002.  
  1003.     fflush(stdout);
  1004.     pager off;
  1005.     ch = gets(str);
  1006.     pager on;
  1007.     if (ch == NULL) {
  1008.         msg("^D\n");
  1009.         log("EOF");
  1010.         fflush(stdout);
  1011.     }
  1012.     return ch;
  1013. }
  1014.  
  1015. char *cpmform(fn)
  1016. char *fn; {
  1017.     static char buf[13];
  1018.     register int cnt, scnt;
  1019.     
  1020.     for (scnt = 0, cnt = 0; cnt < 8 && fn[cnt] != '.' && fn[cnt] != '\0'; cnt++, scnt++)
  1021.         buf[scnt] = ToUpper(fn[cnt]);
  1022.     while (scnt < 8)
  1023.         buf[scnt++] = ' ';
  1024.     buf[scnt++] = '.';
  1025.     while (fn[cnt] != '.' && fn[cnt] != '\0')
  1026.         cnt++;
  1027.     if (fn[cnt] == '.')
  1028.         cnt++;
  1029.     while (scnt < 12 && fn[cnt] != '\0') {
  1030.         buf[scnt++] = ToUpper(fn[cnt]);
  1031.         cnt++;
  1032.     }
  1033.     buf[scnt] = '\0';
  1034.     return buf;
  1035. }
  1036.  
  1037. char *upstr(s)
  1038. char *s; {
  1039.     static char sbuf[512];
  1040.     register char *cp, *dp;
  1041.     
  1042.     for (cp = s, dp = sbuf; *cp != '\0'; cp++, dp++)
  1043.         *dp = ToUpper(*cp);
  1044.     *dp = '\0';
  1045.     return sbuf;
  1046. }
  1047.  
  1048. char *today() {
  1049.     long now;
  1050.     struct tm *date;
  1051.     static char buf[11];
  1052.     
  1053.     time(&now);
  1054.     date = localtime(&now);
  1055.     sprintf(buf, "%d/%d/%d", date->tm_mon + 1, date->tm_mday, date->tm_year);
  1056.     return buf;
  1057. }
  1058.  
  1059. validudl(cmd)
  1060. char *cmd; {
  1061.     if (cmd[0] == '\0')
  1062.         return 0;
  1063.     if (Index(cmd, '%') != RIndex(cmd, '%'))
  1064.         return 0;
  1065.     if (Index(cmd, '%') == (char *) 0) {
  1066.         strcat(cmd, " %s");
  1067.         return 1;
  1068.     }
  1069.     if (*(Index(cmd, '%') + 1) != 's')
  1070.         return 0;
  1071.     return 1;
  1072. }
  1073. SHAR_EOF
  1074. if test 15435 -ne "`wc -c < 'udl.c'`"
  1075. then
  1076.     echo shar: error transmitting "'udl.c'" '(should have been 15435 characters)'
  1077. fi
  1078. fi
  1079. echo shar: extracting "'user.c'" '(16898 characters)'
  1080. if test -f 'user.c'
  1081. then
  1082.     echo shar: will not over-write existing file "'user.c'"
  1083. else
  1084. cat << \SHAR_EOF > 'user.c'
  1085. /*
  1086.  * %W% %E% %U% ncoast!bsa %Z%
  1087.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  1088.  */
  1089.  
  1090. #ifndef lint
  1091. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  1092. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  1093. #endif  lint
  1094.  
  1095. #include "ua.h"
  1096.  
  1097. struct user user;
  1098. struct _himsg *hicnts;
  1099.  
  1100. getuser(name, buf)
  1101.     char *name;
  1102.     struct user *buf;
  1103.     {
  1104.     FILE *bfd;
  1105.     char line[1024], lcuname[33], *p, *q;
  1106.  
  1107.     if ((bfd = fopen(PASSWD, "r")) == NULL)
  1108.     {
  1109.     log("Error %d opening %s", errno, PASSWD);
  1110.     panic("passwd");
  1111.     }
  1112.     for (p = name, q = lcuname; *p != '\0' && p - name <= 32; p++, q++)
  1113.     *q = ToLower(*p);
  1114.     *q = '\0';
  1115.     while (fgets(line, sizeof line, bfd) != NULL)
  1116.     if (strncmp(line, lcuname, strlen(lcuname)) == 0 && line[strlen(lcuname)] == ':')
  1117.         {
  1118.         fclose(bfd);
  1119.         buf->u_name[0] = '\0';
  1120.         buf->u_pass[0] = '\0';
  1121.         buf->u_access = 0;
  1122.         buf->u_login[0] = '\0';
  1123.         buf->u_llen = 0;
  1124.         buf->u_nbull = 0;
  1125.         buf->u_lconf[0] = '\0';
  1126. #ifndef SYS3
  1127.         /* jpn - this used to be a scanf that didn't work on BSD */
  1128.         pwparse(line, buf);
  1129. #else
  1130.         sscanf(line, "%[^:]:%[^:]:%hd:%[^:]:%hd:%hd:%[^:]", buf->u_name, buf->u_pass, &buf->u_access, buf->u_login, &buf->u_llen, &buf->u_nbull, buf->u_lconf);
  1131. #endif
  1132.         buf->u_lconf[strlen(buf->u_lconf) - 1] = '\0';
  1133.         return 1;
  1134.         }
  1135.     fclose(bfd);
  1136.     return 0;
  1137.     }
  1138.  
  1139. #ifndef SYS3
  1140. pwparse(line, buf)
  1141. char *line;
  1142. struct user *buf;
  1143.     {
  1144.     char *index();
  1145.     register char *p;
  1146.  
  1147.     /* jpn - this used to be a single scanf that didn't work on BSD */
  1148.     /* because the %[ format MUST match one character to succeed */
  1149.     p = line;
  1150.     sscanf(p, "%[^:]", buf->u_name);
  1151.     if ((p = index(p, ':')) == 0) return; else ++p;
  1152.     sscanf(p, "%[^:]", buf->u_pass);
  1153.     if ((p = index(p, ':')) == 0) return; else ++p;
  1154.     sscanf(p, "%hd", &buf->u_access);
  1155.     if ((p = index(p, ':')) == 0) return; else ++p;
  1156.     sscanf(p, "%[^:]", buf->u_login);
  1157.     if ((p = index(p, ':')) == 0) return; else ++p;
  1158.     sscanf(p, "%hd", &buf->u_llen);
  1159.     if ((p = index(p, ':')) == 0) return; else ++p;
  1160.     sscanf(p, "%hd", &buf->u_nbull);
  1161.     if ((p = index(p, ':')) == 0) return; else ++p;
  1162.     sscanf(p, "%[^:]", buf->u_lconf);
  1163.     }
  1164. #endif
  1165.  
  1166. putuser(name, ubuf)
  1167.     char *name;
  1168.     struct user *ubuf;
  1169.     {
  1170.     FILE *fd, *tfd;
  1171.     char line[1024], *tempfile = mktemp("/tmp/UptXXXXXX"), lcname[33], *p, *q;
  1172.     static char lockfile[] = "userfil.lock";
  1173.     short flag;
  1174.  
  1175.     CRIT();
  1176.     mklock(lockfile);
  1177.     if ((fd = fopen(PASSWD, "r")) == NULL)
  1178.     {
  1179.     log("Error %d opening %s", errno, PASSWD);
  1180.     panic("passwd");
  1181.     }
  1182.     if ((tfd = fopen(tempfile, "w")) == NULL)
  1183.     {
  1184.     log("Error %d opening %s", errno, tempfile);
  1185.     panic("tmp");
  1186.     }
  1187.     flag = 0;
  1188.     for (p = name, q = lcname; *p != '\0' && p - name < 33; p++, q++)
  1189.     *q = ToLower(*p);
  1190.     *q = 0;
  1191.     while (fgets(line, sizeof line, fd) != NULL)
  1192.     if (strncmp(line, lcname, strlen(lcname)) == 0 && line[strlen(lcname)] == ':')
  1193.         {
  1194.         fprintf(tfd, "%s:%s:%d:%s:%d:%d:%s\n", ubuf->u_name, ubuf->u_pass, ubuf->u_access, ubuf->u_login, ubuf->u_llen, (s_cmp(ubuf->u_name, "guest") == 0? 0: ubuf->u_nbull), (s_cmp(ubuf->u_name, "guest") == 0? "": ubuf->u_lconf));
  1195.         flag++;
  1196.         }
  1197.     else
  1198.         fputs(line, tfd);
  1199.     if (!flag)
  1200.     fprintf(tfd, "%s:%s:%d:%s:%d:%d:%s\n", ubuf->u_name, ubuf->u_pass, ubuf->u_access, ubuf->u_login, ubuf->u_llen, (s_cmp(ubuf->u_name, "guest") == 0? 0: ubuf->u_nbull), (s_cmp(ubuf->u_name, "guest") == 0? "": ubuf->u_lconf));
  1201.     fclose(fd);
  1202.     fclose(tfd);
  1203.     unlink(PASSWD);
  1204.     if (copylink(tempfile, PASSWD) < 0)
  1205.     {
  1206.     log("Error %d copylinking %s to %s", errno, tempfile, PASSWD);
  1207.     panic("copylink");
  1208.     }
  1209.     unlink(tempfile);
  1210.     rmlock(lockfile);
  1211.     NOCRIT();
  1212.     }
  1213.  
  1214. writehigh(hilist)
  1215.     struct _himsg *hilist;
  1216.     {
  1217.     FILE *hp, *f;
  1218.     static char line[1024], hirec[1024];    /* 68000's have limited frames */
  1219.     char *tmpf = mktemp("/tmp/RcXXXXXX");
  1220.     char *eofflag;
  1221.     static char lockfile[] = "newmsgs.lock";
  1222.     struct _himsg *hptr;
  1223.  
  1224.     if (s_cmp(user.u_name, "guest") == 0)
  1225.         return;    /* don't write GUEST hirecs! */
  1226.     CRIT();
  1227.     if ((f = fopen(tmpf, "w")) == NULL)
  1228.     {
  1229.     log("Error %d opening %s", errno, tmpf);
  1230.     panic("tmp");
  1231.     }
  1232.     if ((hp = fopen(NEWMSGS, "r")) == NULL)
  1233.     {
  1234.     log("Error %d opening %s", errno, NEWMSGS);
  1235.     fclose(f);
  1236.     unlink(tmpf);
  1237.     panic("userind");
  1238.     }
  1239.     mklock(lockfile);
  1240.     sprintf(line, "%s:", user.u_name);
  1241.     while ((eofflag = fgets(hirec, sizeof hirec, hp)) != NULL) {
  1242.     if (strncmp(hirec, line, strlen(line)) == 0)
  1243.         break;
  1244.     fputs(hirec, f);
  1245.     }
  1246.     if (!eofflag)
  1247.         while ((eofflag = fgets(hirec, sizeof hirec, hp)) != NULL)
  1248.             if (hirec[0] != '\t' && hirec[0] != ' ')
  1249.                    break;
  1250.     fputs(line, f);
  1251.     putc('\n', f);
  1252.     for (hptr = hilist; hptr != NULL; hptr = hptr->hi_next)
  1253.         fprintf(f, "\t%s%c %d\n", hptr->hi_conf, (hptr->hi_uns == HI_UNSUB? '!': ':'), hptr->hi_num);
  1254.     if (!eofflag && hirec[0] != '\t' && hirec[0] != ' ')
  1255.         fputs(hirec, f);
  1256.     if (!eofflag)
  1257.         while (fgets(hirec, sizeof hirec, hp) != NULL)
  1258.             fputs(hirec, f);
  1259.     fclose(f);
  1260.     fclose(hp);
  1261.     unlink(NEWMSGS);
  1262.     if (copylink(tmpf, NEWMSGS) < 0)
  1263.     {
  1264.     log("Error %d copylinking %s to %s", errno, tmpf, NEWMSGS);
  1265.     panic("copylink");
  1266.     }
  1267.     unlink(tmpf);
  1268.     rmlock(lockfile);
  1269.     NOCRIT();
  1270.     }
  1271.  
  1272. struct _himsg *readhigh(foruser)
  1273.     struct user *foruser;
  1274.     {
  1275.     static char hirec[1024];
  1276.     char uidx[40], *p, *q;
  1277.     FILE *f;
  1278.     struct _himsg *workp, *initp, *lastp;
  1279.  
  1280.     strcpy(uidx, foruser->u_name);
  1281.     strcat(uidx, ":");
  1282.     if ((f = fopen(NEWMSGS, "r")) == NULL)
  1283.     return NULL;
  1284.     while (fgets(hirec, sizeof hirec, f) != NULL)
  1285.     if (strncmp(hirec, uidx, strlen(uidx)) == 0)
  1286.         break;
  1287.     if (feof(f))
  1288.     {
  1289.     fclose(f);
  1290.     return NULL;
  1291.     }
  1292.     workp = NULL;
  1293.     initp = NULL;
  1294.     while (fgets(hirec, sizeof hirec, f) != NULL && (hirec[0] == ' ' || hirec[0] == '\t')) {
  1295.         hirec[strlen(hirec) - 1] = '\0';
  1296.     for (p = hirec; *p == ' ' || *p == '\t'; p++)
  1297.             ;
  1298.         for (q = uidx; *p != ' ' && *p != '\t' && *p != '\0' && *p != ':' && *p != '!'; p++)
  1299.         *q++ = *p;
  1300.     *q = '\0';
  1301.     while (*p == ' ' || *p == '\t')
  1302.         p++;
  1303.         if (*p == '!') {    /* unsubscribed... */
  1304.         if ((workp = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL)
  1305.             {
  1306.             log("Error %d allocating _himsg for %s", errno, uidx);
  1307.             panic("alloc");
  1308.             }
  1309.         strcpy(workp->hi_conf, uidx);
  1310.         workp->hi_num = atoi(++p);
  1311.         workp->hi_next = initp;
  1312.         workp->hi_uns = HI_UNSUB;
  1313.         initp = workp;
  1314.         continue;
  1315.         }
  1316.     if (*p != ':') {
  1317.         log("Invalid format of userind record: ``%s''", hirec);
  1318.         puts("Your index is garbled; some conference\nhigh-message counts may be lost.");
  1319.         break;
  1320.     }
  1321.     if ((workp = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL)
  1322.         {
  1323.         log("Error %d allocating _himsg for %s", errno, uidx);
  1324.         panic("alloc");
  1325.         }
  1326.     strcpy(workp->hi_conf, uidx);
  1327.     workp->hi_num = atoi(++p);
  1328.     workp->hi_next = initp;
  1329.     workp->hi_uns = HI_SUBSCR;
  1330.     initp = workp;
  1331.     }
  1332.     fclose(f);
  1333.     return initp;
  1334.     }
  1335.  
  1336. newuser()
  1337.     {
  1338.     struct user nubuf, junk;
  1339.     char line[256], *p;
  1340.  
  1341.     log("Entered newuser module.");
  1342.     cat(NEWUSER);
  1343.  
  1344. Again:
  1345.     printf("\nDo you still want to become a user (N)? ");
  1346.     gets(line);
  1347.     log("Become user? %s", line);
  1348.     if (ToLower(line[0]) != 'y')
  1349.     return;
  1350.     do
  1351.     {
  1352.     printf("What name would you like to use on this system?  It should not be\nmore than 32 letters long: ");
  1353.     gets(line);
  1354.     log("Name: %s", line);
  1355.     if (line[0] == '\0' || line[0] == ' ')
  1356.         {
  1357.         line[0] = '?';
  1358.         p = line;
  1359.         continue;
  1360.         }
  1361.     for (p = line; *p != '\0'; p++)
  1362.         if (*p == ':')
  1363.         {
  1364.         puts("Sorry, no colons allowed; they cause nasty surprises.");
  1365.         log("Illegal colon in name");
  1366.         break;
  1367.         }
  1368.     }
  1369.     while (*p != NULL);
  1370.     strncpy(nubuf.u_name, line, 32);
  1371.     nubuf.u_name[32] = '\0';
  1372.     line[0] = '\0';
  1373.     do
  1374.     {
  1375.     if (line[0] != 0)
  1376.         puts("You made a typing error.");
  1377.     strcpy(line, getpass("Please enter a password of three to eight characters.\nIt will not be displayed: "));
  1378.     log("Pass: %s", line);
  1379.     }
  1380.     while (strlen(line) < 3 || strcmp(line, getpass("Please re-enter it, just to make sure: ")) != 0);
  1381.     strcpy(nubuf.u_pass, line);
  1382.     do
  1383.     {
  1384.     printf("How many characters per line are on your terminal?\nPlease enter a number from 40 to 132, or <ENTER> for 80: ");
  1385.     gets(line);
  1386.     log("Line: %s", line);
  1387.     if (line[0] == '\0')
  1388.         nubuf.u_llen = 80;
  1389.     else
  1390.         nubuf.u_llen = atoi(line);
  1391.     }
  1392.     while (nubuf.u_llen < 40 || nubuf.u_llen > 132);
  1393.     printf("\nName:\t%s\nPass:\t%s\nLine:\t%d\n\nIs this correct (N)? ", nubuf.u_name, nubuf.u_pass, nubuf.u_llen);
  1394.     gets(line);
  1395.     log("Okay? %s", line);
  1396.     if (ToLower(line[0]) != 'y')
  1397.     goto Again;
  1398.     puts("Encrypting password, please wait...");
  1399.     strcpy(nubuf.u_pass, crypt(nubuf.u_pass, nubuf.u_pass) + 2);
  1400.     strcpy(nubuf.u_login, user.u_login);/* default login name ( guest ?) */
  1401.     nubuf.u_access = user.u_llen;    /* since we don't use u_llen here */
  1402.     nubuf.u_nbull = 0;            /* no bulletins read yet */
  1403.     puts("Recording user information...");
  1404.     for (p = nubuf.u_name; *p != '\0'; p++)
  1405.     *p = ToLower(*p);
  1406.     if (getuser(nubuf.u_name, &junk))
  1407.     {
  1408.     puts("Sorry, but that name's already in use.  Please choose another.");
  1409.     goto Again;
  1410.     }
  1411.     putuser(nubuf.u_name, &nubuf);
  1412.     user = nubuf;
  1413.     }
  1414.  
  1415. userctl(s)
  1416.     char *s;
  1417.     {
  1418.     char line[256], *p, *q;
  1419.     struct user ubuf;
  1420.     short cflag, pflag;
  1421.  
  1422.     if (user.u_access != A_WITNESS)
  1423.     {
  1424.     if (strcmp(user.u_name, "guest") == 0) {
  1425.         log("Security violation:  userctl by GUEST");
  1426.         puts("Sorry, but GUEST can't change himself.");
  1427.         return 1;
  1428.     }
  1429.     pflag = 1;
  1430.     log("Userctl by non-Witness; restricting control modes.");
  1431.     puts("Since you're not a Fairwitness, you can only change some things about\nyourself, like your password.");
  1432.     strcpy(line, user.u_name);
  1433.     }
  1434.     else
  1435.     {
  1436.     line[0] = '\0';
  1437.     pflag = 0;
  1438.     for (p = s; *p != '\0'; p++)
  1439.         if (*p == ' ')
  1440.         {
  1441.         strcpy(line, ++p);
  1442.         break;
  1443.         }
  1444.     if (line[0] == '\0')
  1445.         {
  1446.         printf("Examine which user: ");
  1447.         gets(line);
  1448.         log("User: %s", line);
  1449.         if (line[0] == '\0')
  1450.         return 1;
  1451.         for (p = line; *p != '\0'; p++)
  1452.         *p = ToLower(*p);
  1453.         }
  1454.     line[32] = '\0';
  1455.     }
  1456.     if (!getuser(line, &ubuf))
  1457.     if (pflag)
  1458.         {
  1459.         log("Can't locate current user in the userfile.");
  1460.         panic("user");
  1461.         }
  1462.     else
  1463.         {
  1464.         printf("No such user.  Create him (N)? ");
  1465.         strcpy(ubuf.u_name, line);
  1466.         gets(line);
  1467.         log("New user? %s", line);
  1468.         if (ToLower(line[0]) != 'y')
  1469.         return 1;
  1470.         ubuf.u_pass[0] = '\0';
  1471.         ubuf.u_access = A_USER;
  1472.         ubuf.u_llen = 80;
  1473.         ubuf.u_nbull = 0;
  1474.         cflag = 0;
  1475.         }
  1476.     else if (strlen(ubuf.u_pass) == 0)
  1477.     cflag = 0;
  1478.     else
  1479.     cflag = 1;
  1480.     for (;;)
  1481.     {
  1482.     printf("\nName:\t%s\nPass:\t%s%s\nAccess:\t%s\nLogin:\t%s\n%s:\t%d\nLogin conference: %s\n\nChange Name, Pass, Access, Login, %s,\nDefault Login Conference; Quit; or Save: ", ubuf.u_name, ubuf.u_pass,
  1483.         (cflag? " (encrypted)": ""), (ubuf.u_access==A_NONE? "None": (ubuf.u_access==A_GUEST? "Guest": (ubuf.u_access==A_USER? "Ordinary user": (ubuf.u_access==A_SYSTEM? "System": (ubuf.u_access==A_FILES? "Files":
  1484.         (ubuf.u_access==A_WITNESS? "Fairwitness": "User maker")))))), ubuf.u_login, (ubuf.u_access==A_MKUSER? "DftAxs": "Width"), ubuf.u_llen, ubuf.u_lconf, (ubuf.u_access==A_MKUSER? "Default Access": "Width"));
  1485.     gets(line);
  1486.     log("Change: %s", line);
  1487.     switch (line[0])
  1488.         {
  1489.         case 'N':
  1490.         case 'n':
  1491.         if (pflag)
  1492.             {
  1493.             log("Security violation: Attempted to change name.");
  1494.             puts("You can't do that.");
  1495.             break;
  1496.             }
  1497.         printf("Enter new name: ");
  1498.         gets(line);
  1499.         log("Name: %s", line);
  1500.         if (line[0] == '\0')
  1501.             break;
  1502.         for (p = line; *p != '\0'; p++)
  1503.             if (*p == ':')
  1504.             {
  1505.             log("Illegal colon in name.");
  1506.             puts("Can't put a colon in a user name.");
  1507.             break;
  1508.             }
  1509.         for (p = line, q = ubuf.u_name; *p != '\0'; p++, q++)
  1510.             *q = ToLower(*p);
  1511.         *q = '\0';
  1512.         break;
  1513.         case 'P':
  1514.         case 'p':
  1515.         strcpy(line, getpass("Enter new password: "));
  1516.         if (line[0] == '\0')
  1517.             break;
  1518.         strcpy(ubuf.u_pass, line);
  1519.         cflag = 0;        /* it's not encrypted now */
  1520.         break;
  1521.         case 'A':
  1522.         case 'a':
  1523.         if (pflag)
  1524.             {
  1525.             log("Security violation: Attempted to change access level.");
  1526.             puts("You can't do that.");
  1527.             break;
  1528.             }
  1529.         printf("Access: None, Guest, User, Files, System, Witness, Makeuser? ");
  1530.         gets(line);
  1531.         log("Access: %s", line);
  1532.         if ((ToLower(line[0]) == 'a' || ubuf.u_access == A_WITNESS) && strcmp(user.u_name, SYSOP) != 0)
  1533.             {
  1534.             puts("Sorry, only the sysop can administer Witness privileges.");
  1535.             log("Security violation: WITNESS administering WITNESS");
  1536.             break;
  1537.             }
  1538.         switch (line[0])
  1539.             {
  1540.             case 'g':
  1541.             case 'G':
  1542.             ubuf.u_access = A_GUEST;
  1543.             break;
  1544.             case 'n':
  1545.             case 'N':
  1546.             ubuf.u_access = A_NONE;
  1547.             break;
  1548.             case '\0':
  1549.             break;
  1550.             case 'u':
  1551.             case 'U':
  1552.             ubuf.u_access = A_USER;
  1553.             break;
  1554.             case 's':
  1555.             case 'S':
  1556.             ubuf.u_access = A_SYSTEM;
  1557.             break;
  1558.             case 'w':
  1559.             case 'W':
  1560.             ubuf.u_access = A_WITNESS;
  1561.             break;
  1562.             case 'm':
  1563.             case 'M':
  1564.             ubuf.u_access = A_MKUSER;
  1565.             break;
  1566.             case 'f':
  1567.             case 'F':
  1568.                 ubuf.u_access = A_FILES;
  1569.                 break;
  1570.             default:
  1571.             puts("What?  Access unchanged.");
  1572.             }
  1573.         break;
  1574.         case 'L':
  1575.         case 'l':
  1576.         printf("Enter the login name to be used: ");
  1577.         gets(line);
  1578.         log("Login name: %s", line);
  1579.         line[8] = '\0';
  1580.         strcpy(ubuf.u_login, line);
  1581.         break;
  1582.             case 'D':
  1583.             case 'd':
  1584.                 printf("Enter the default login conference: ");
  1585.                 gets(line);
  1586.                 log("Login conference: %s", line);
  1587.                 if (!isconf(line))
  1588.                     puts("That conference doesn't exist.");
  1589.                 else if (uisunsub(ubuf.u_name, line))
  1590.                     printf("%s isn't subscribed to %s.\n", ubuf.u_name, line);
  1591.                 else
  1592.                     strcpy(ubuf.u_lconf, line);
  1593.                 break;
  1594.         case 'W':
  1595.         case 'w':
  1596.         if (ubuf.u_access == A_MKUSER) {
  1597.             printf("Default Access: None, Guest, User, Files, System? ");
  1598.             gets(line);
  1599.             log("DftAxs: %s", line);
  1600.             if (ToLower(line[0]) == 'a') {
  1601.                 puts("I don't think you really want to make every user a Fairwitness.");
  1602.                 log("Security violation: DftAxs == A_WITNESS?");
  1603.                 break;
  1604.             }
  1605.             switch (line[0]) {
  1606.                 case 'g':
  1607.                 case 'G':
  1608.                 ubuf.u_llen = A_GUEST;
  1609.                 break;
  1610.                 case 'n':
  1611.                 case 'N':
  1612.                 ubuf.u_llen = A_NONE;
  1613.                 break;
  1614.                 case '\0':
  1615.                 break;
  1616.                 case 'u':
  1617.                 case 'U':
  1618.                 ubuf.u_llen = A_USER;
  1619.                 break;
  1620.                 case 's':
  1621.                 case 'S':
  1622.                 ubuf.u_access = A_SYSTEM;
  1623.                 break;
  1624.                 case 'm':
  1625.                 case 'M':
  1626.                 puts("Default access is user maker???");
  1627.                 log("Attempted to make default access == MAKEUSER?");
  1628.                 break;
  1629.                 case 'f':
  1630.                 case 'F':
  1631.                     ubuf.u_access = A_FILES;
  1632.                     break;
  1633.                 default:
  1634.                 puts("What?  Default access unchanged.");
  1635.             }
  1636.         }
  1637.         else {
  1638.             printf("Enter new line length, 40-132: ");
  1639.             gets(line);
  1640.             log("Line length: %s", line);
  1641.             if (line[0] == '\0')
  1642.                 break;
  1643.             ubuf.u_llen = atoi(line);
  1644.         }
  1645.         break;
  1646.         case 'Q':
  1647.         case 'q':
  1648.         printf("Abort user examine, are you sure (N)? ");
  1649.         gets(line);
  1650.         log("Abort? %s", line);
  1651.         if (ToLower(line[0]) != 'y')
  1652.             break;
  1653.         return 1;
  1654.         case 'S':
  1655.         case 's':
  1656.         if (!cflag)
  1657.             {
  1658.             puts("Encrypting password, please wait...");
  1659.             strcpy(ubuf.u_pass, crypt(ubuf.u_pass, ubuf.u_pass) + 2);
  1660.             }
  1661.         putuser(ubuf.u_name, &ubuf);
  1662.         if (strcmp(ubuf.u_name, user.u_name) == 0)
  1663.             user = ubuf;
  1664.         return 1;
  1665.         default:
  1666.         puts("What?  Please enter one of N, P, L, A, D, or S.");
  1667.         }
  1668.     }
  1669.     }
  1670.  
  1671. userlist()
  1672.     {
  1673.     FILE *bfd;
  1674.     char line[1024], *p;
  1675.     short lcnt;
  1676.     struct user buf;
  1677.  
  1678.     if ((bfd = fopen(PASSWD, "r")) == NULL)
  1679.     {
  1680.     log("Error %d opening %s", errno, PASSWD);
  1681.     panic("passwd");
  1682.     }
  1683.     puts("\nList of UNaXcess users:\n");
  1684.     lcnt = 0;
  1685.     while (fgets(line, 1024, bfd) != NULL)
  1686.     {
  1687. #ifndef SYS3
  1688.     pwparse(line, &buf);
  1689. #else
  1690.     sscanf(line, "%[^:]:%[^:]:%hd:%[^:]:%hd", buf.u_name, buf.u_pass, &buf.u_access, buf.u_login, &buf.u_llen);
  1691. #endif
  1692.     for (p = buf.u_name; *p != NULL; p++)
  1693.         *p = ToUpper(*p);
  1694.     printf("%-32.32s Access: %s\n", buf.u_name, (buf.u_access==A_NONE?
  1695.         "None": (buf.u_access==A_GUEST? "Guest": (buf.u_access==A_USER?
  1696.         "Normal": (buf.u_access==A_WITNESS? "Fairwitness": (buf.u_access==A_SYSTEM? "System": (user.u_access==A_FILES? "Files": "(make a user)")))))));
  1697.     if (++lcnt % 16 == 0)
  1698.         if (!cont())
  1699.         break;
  1700.     }
  1701.     fclose(bfd);
  1702.     return 1;
  1703.     }
  1704. SHAR_EOF
  1705. if test 16898 -ne "`wc -c < 'user.c'`"
  1706. then
  1707.     echo shar: error transmitting "'user.c'" '(should have been 16898 characters)'
  1708. fi
  1709. fi
  1710. exit 0
  1711. #    End of shell archive
  1712.